package cn.xiongxf.mq.listener;

import cn.xiongxf.domain.CourseOrder;
import cn.xiongxf.dto.PayOrder2MQDTO;
import cn.xiongxf.service.ICourseOrderService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;

import java.nio.charset.StandardCharsets;

@RocketMQTransactionListener(txProducerGroup = "tx-producer-group-courseorder")  // MQ事务监听器
@Slf4j
public class CourseOrderTransactionListener implements RocketMQLocalTransactionListener {
    @Autowired
    private ICourseOrderService courseOrderService;

    /**
     * 执行本地事务：保存订单和明细
     * @param message 消息对象 - 支付订单
     * @param arg 扩展参数 - 订单和明细
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object arg) {
        // 获取订单和订单明细?
        try {
//            if (null != arg && arg instanceof CourseOrder){  // null instance of Object 是false
            if (arg instanceof CourseOrder){
                CourseOrder courseOrder = (CourseOrder) arg;
                courseOrderService.saveOrderAndItems(courseOrder);
                log.info("成功保存订单和订单明细：{}",courseOrder);
                // 本地事务提交
                return RocketMQLocalTransactionState.COMMIT;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 本地事务回滚
        return RocketMQLocalTransactionState.ROLLBACK;
    }

    /**
     * 检查本地事务：检查订单和订单明细是否保存成功
     * @param message 消息对象 - 支付订单
     */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        // 拿到订单号，检查DB中是否有课程订单
        // 消息被转成了byte[]
        // Message -> byte[] -> JSON String -> Object
        byte[] bytes = (byte[]) message.getPayload();
        if (bytes == null || bytes.length == 0) return RocketMQLocalTransactionState.UNKNOWN;  // 传入的对象可以为null，最终返回的byte数组不为nul
        // 获取支付订单DTO对象，获取订单号
        String jsonString = new String(bytes, StandardCharsets.UTF_8);
        PayOrder2MQDTO payOrder2MQDTO = JSON.parseObject(jsonString, PayOrder2MQDTO.class);
        // 根据订单号查询是否保存成功
        CourseOrder order = courseOrderService.selectOne(new EntityWrapper<CourseOrder>().eq("order_no", payOrder2MQDTO.getOrderNo()));
        log.info("检查本地事务：{}，{}", message, order);
        // 订单保存成功就提交，否则就回滚
        return order != null ? RocketMQLocalTransactionState.COMMIT : RocketMQLocalTransactionState.ROLLBACK;
    }
}
